package com.siashan.toolkit.phone.parser;

import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;

import java.util.Locale;

/**
 * 手机号码归属地工具类
 *
 * @author siashan
 * @since v1.0.2
 */
public class PhoneUtil {


    /**
     * 默认区域编码
     */
    private static final String COUNTRYCODE = "86";

    /**
     * 手机号工具类
     */
    private static PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance();

    /**
     * 运营商
     */
    private static PhoneNumberToCarrierMapper carrierMapper = PhoneNumberToCarrierMapper.getInstance();

    /**
     * 归属地
     */
    private static PhoneNumberOfflineGeocoder geocoder = PhoneNumberOfflineGeocoder.getInstance();

    /**
     * 根据国家代码和手机号  判断手机号是否有效
     *
     * @param phoneNumber   手机号码
     * @param countryCode   国家代码
     * @return 是否有效
     */
    public static boolean isValidNumber(String phoneNumber, String countryCode) {
        return phoneNumberUtil.isValidNumber(initPN(phoneNumber, countryCode));
    }

    /**
     * 根据手机号  判断手机号是否有效
     *
     * @param phoneNumber   手机号码
     * @return 是否有效
     */
    public static boolean isValidNumber(String phoneNumber) {
        return isValidNumber(phoneNumber, COUNTRYCODE);

    }


    /**
     * 根据国家代码和手机号  判断手机运营商
     *
     * @param phoneNumber   手机号
     * @param countryCode   国家代码
     * @return 手机运营商
     */
    public static String getCarrier(String phoneNumber, String countryCode) {
        return getCarrier(initPN(phoneNumber, countryCode));
    }

    /**
     * 根据手机号  判断手机运营商
     *
     * @param phoneNumber   手机号
     * @return 手机运营商
     */
    public static String getCarrier(String phoneNumber) {
        return getCarrier(phoneNumber,COUNTRYCODE);
    }

    /**
     * 根据国家代码和手机号  判断手机运营商
     *
     * @param phoneNumber   手机号
     * @return 手机运营商
     */
    public static String getCarrier(Phonenumber.PhoneNumber phoneNumber) {
        return carrierMapper.getNameForNumber(phoneNumber, Locale.CHINESE);
    }

    /**
     * 根据手机号和国家代码获取归属地
     *
     * @param countryCode  国家代码
     * @param phoneNumber 手机号码
     * @return 手机号码归属地
     */
    public static String getGeo(String phoneNumber, String countryCode) {
        return getGeo(initPN(phoneNumber, countryCode));
    }

    /**
     * 根据手机号和国家代码获取归属地
     *
     * @param phoneNumber 手机号码类
     * @return 手机号码归属地
     */
    public static String getGeo(Phonenumber.PhoneNumber phoneNumber) {
        String areaName = geocoder.getDescriptionForNumber(phoneNumber, Locale.CHINESE);
        if (isEmpty(areaName) || areaName.length() < 3) {
            return "";
        }
        return areaName;
    }

    /**
     * 获取手机号码归属地
     *
     * @param phoneNumber 手机号码
     * @return 归属地
     */
    public static String getGeo(String phoneNumber) {
        return getGeo(phoneNumber, COUNTRYCODE);
    }

    /**
     * 判断号码归属地是否匹配
     *
     * @param geo  归属地
     * @param phoneNumber  手机号码
     * @return 是否匹配
     */
    public static boolean isGeoMatch(String geo, String phoneNumber) {
        if (isEmpty(geo) || isEmpty(phoneNumber)) {
            return false;
        }
        return geo.equals(getGeo(phoneNumber));
    }


    /**
     * 初始化构建PhoneNumber对象
     *
     * @param phoneNumber    手机号
     * @param countryCode    国家代码
     * @return PhoneNumber对象
     */
    private static Phonenumber.PhoneNumber initPN(String phoneNumber, String countryCode) {
        Phonenumber.PhoneNumber pn = new Phonenumber.PhoneNumber();
        pn.setCountryCode(Integer.parseInt(countryCode));
        pn.setNationalNumber(Long.parseLong(phoneNumber));
        return pn;
    }


    /**
     * 获取手机号详细信息
     *
     * @param phoneNumber  手机号码
     * @return 手机号码详细信息
     */
    public static PhoneInfo getPhoneInfo(String phoneNumber) {
        Phonenumber.PhoneNumber pn = initPN(phoneNumber, COUNTRYCODE);
        PhoneInfo phone = new PhoneInfo();
        // 手机号码
        phone.setPhoneNumber(phoneNumber);
        // 判断手机号码是否有效
        phone.setValid(phoneNumberUtil.isValidNumber(pn));
        // 号码归属地
        phone.setGeo(getGeo(pn));
        // 运行商
        phone.setCarrier(getCarrier(pn));
        return phone;
    }

    /**
     * 判断字符串是否为空
     *
     * @param str 字符串
     * @return 是否为空
     */
    private static boolean isEmpty(String str) {
        return null == str || "".equals(str.trim());
    }


    public static void main(String[] args) {
        System.out.println(getGeo("182360007232"));
        System.out.println(isGeoMatch("郑州市", "18736000821"));
        System.out.println(getCarrier("18736000821", "86"));
        System.out.println(getPhoneInfo("18736000821"));
    }

}
